package com.university.evaluation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.university.evaluation.common.ResponseResult;
import com.university.evaluation.domain.dto.StudentInfoDTO;
import com.university.evaluation.entity.StudentInfo;
import com.university.evaluation.enums.RespEnum;
import com.university.evaluation.mapper.StudentInfoMapper;
import com.university.evaluation.service.StudentInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class StudentInfoServiceImpl extends ServiceImpl<StudentInfoMapper, StudentInfo> implements StudentInfoService {

    @Override
    public ResponseResult<StudentInfo> findByStudentId(String studentId) {
        if (!StringUtils.hasText(studentId)) {
            return ResponseResult.failure(RespEnum.FAILURE.getCode(), "学号不能为空");
        }
        try {
            // studentId 是主键，直接使用 getById
            StudentInfo studentInfo = this.getById(studentId.trim());
            if (studentInfo != null) {
                log.info("成功获取到学号为 {} 的学生信息", studentId);
                return ResponseResult.success("获取学生信息成功", studentInfo);
            } else {
                log.warn("未能找到学号为 {} 的学生信息", studentId);
                return ResponseResult.failure(RespEnum.NOT_FOUND);
            }
        } catch (Exception e) {
            log.error("根据学号 {} 查询学生信息时发生异常", studentId, e);
            return ResponseResult.failure(RespEnum.FAILURE.getCode(), "获取学生信息时发生内部错误");
        }
    }

    @Override
    @Transactional
    public ResponseResult<StudentInfo> updateStudentInfo(String studentId, StudentInfoDTO studentInfoDTO) {
        try {
            StudentInfo existingInfo = this.getById(studentId);
            if (existingInfo == null) {
                return ResponseResult.failure(RespEnum.NOT_FOUND.getCode(), "未找到该学生的信息，无法更新");
            }

            // 使用 BeanUtils.copyProperties 优雅地复制属性
            // 忽略主键和外键，防止被意外修改
            BeanUtils.copyProperties(studentInfoDTO, existingInfo, "studentId", "userId");

            boolean success = this.updateById(existingInfo);
            if (success) {
                log.info("成功更新学号为 {} 的学生信息", studentId);
                return ResponseResult.success("更新成功", existingInfo);
            } else {
                log.error("更新学号为 {} 的学生信息时数据库操作失败", studentId);
                return ResponseResult.failure("更新失败，请稍后再试");
            }
        } catch (Exception e) {
            log.error("更新学号为 {} 的学生信息时发生异常", studentId, e);
            return ResponseResult.failure(RespEnum.FAILURE.getCode(), "更新学生信息时发生内部错误");
        }
    }

    @Override
    public ResponseResult<StudentInfo> findByUserId(Long userId) {
        if (userId == null) {
            return ResponseResult.failure(RespEnum.FAILURE.getCode(), "用户ID不能为空");
        }
        try {
            StudentInfo studentInfo = this.getOne(new LambdaQueryWrapper<StudentInfo>().eq(StudentInfo::getUserId, userId));
            if (studentInfo != null) {
                log.info("成功获取到用户ID为 {} 的学生信息", userId);
                return ResponseResult.success("查询成功", studentInfo);
            } else {
                log.warn("未能找到用户ID为 {} 的学生信息", userId);
                return ResponseResult.failure(RespEnum.NOT_FOUND);
            }
        } catch (Exception e) {
            log.error("根据用户ID {} 查询学生信息时发生异常", userId, e);
            return ResponseResult.failure("查询学生信息时发生异常");
        }
    }

    // --- 以下为 Controller 中调用的其他方法的完整实现 ---

    @Override
    public ResponseResult<StudentInfo> bindStudentInfo(String studentId, StudentInfoDTO studentInfoDTO) {
        log.warn("bindStudentInfo 接口被调用，但尚未实现详细业务逻辑 for {}", studentId);
        // TODO: 在这里实现详细的绑定逻辑，例如：
        // 1. 检查 studentId 是否已存在
        // 2. 检查 DTO 中的 userId 是否已与其他 studentId 绑定
        // 3. 创建或更新 StudentInfo 实体
        return ResponseResult.failure(501, "接口待实现");
    }

    @Override
    public ResponseResult<?> getScoreOverview(String studentId) {
        log.warn("getScoreOverview 接口被调用，但尚未实现详细业务逻辑 for {}", studentId);
        // TODO: 在这里实现查询成绩概览的复杂SQL或业务逻辑
        return ResponseResult.failure(501, "接口待实现");
    }

    @Override
    public ResponseResult<?> getEvaluationStats(String studentId) {
        log.warn("getEvaluationStats 接口被调用，但尚未实现详细业务逻辑 for {}", studentId);
        // TODO: 在这里实现查询评价统计的复杂SQL或业务逻辑
        return ResponseResult.failure(501, "接口待实现");
    }

    @Override
    public ResponseResult<?> getStudentWarnings(String studentId) {
        log.warn("getStudentWarnings 接口被调用，但尚未实现详细业务逻辑 for {}", studentId);
        // TODO: 在这里实现查询预警信息的复杂SQL或业务逻辑
        return ResponseResult.failure(501, "接口待实现");
    }

    @Override
    public ResponseResult<StudentInfo> getStudentInfoById(String studentId) {
        // 直接复用已有方法
        return findByStudentId(studentId);
    }

    @Override
    public ResponseResult<Map<String, Object>> getStudentList(Map<String, Object> params) {
        try {
            Page<StudentInfo> page = new Page<>(
                    Long.parseLong(params.getOrDefault("current", "1").toString()),
                    Long.parseLong(params.getOrDefault("size", "10").toString())
            );

            LambdaQueryWrapper<StudentInfo> wrapper = new LambdaQueryWrapper<>();
            // 示例筛选条件
            if (params.containsKey("studentName")) {
                wrapper.like(StudentInfo::getStudentName, params.get("studentName").toString());
            }
            if (params.containsKey("studentId")) {
                wrapper.like(StudentInfo::getStudentId, params.get("studentId").toString());
            }
            // ... 可以根据 params 添加更多筛选条件 (classId, majorId, etc.)

            page = this.page(page, wrapper);

            Map<String, Object> resultData = new HashMap<>();
            resultData.put("records", page.getRecords());
            resultData.put("total", page.getTotal());
            resultData.put("current", page.getCurrent());
            resultData.put("size", page.getSize());

            log.info("成功获取学生列表, 参数: {}, 返回总数: {}", params, page.getTotal());
            return ResponseResult.success("获取列表成功", resultData);
        } catch (Exception e) {
            log.error("获取学生列表时发生异常, 参数: {}", params, e);
            return ResponseResult.failure(RespEnum.FAILURE.getCode(), "获取学生列表时发生内部错误");
        }
    }

    @Override
    public ResponseResult<?> batchImport(MultipartFile file) {
        log.warn("batchImport 接口被调用，但尚未实现");
        // TODO: 实现Excel文件解析和批量导入的复杂逻辑
        return ResponseResult.failure(501, "接口待实现");
    }

    @Override
    public ResponseResult<List<StudentInfo>> findByClassId(Long classId) {
        try {
            List<StudentInfo> list = this.list(new LambdaQueryWrapper<StudentInfo>().eq(StudentInfo::getClassName, classId)); // 假设按 className 查询
            return ResponseResult.success("查询成功", list);
        } catch (Exception e) {
            log.error("按班级 {} 查询学生时发生异常", classId, e);
            return ResponseResult.failure("按班级查询学生时发生异常");
        }
    }

    @Override
    public ResponseResult<List<StudentInfo>> findByMajorId(Long majorId) {
        try {
            List<StudentInfo> list = this.list(new LambdaQueryWrapper<StudentInfo>().eq(StudentInfo::getMajor, majorId)); // 假设按 major 查询
            return ResponseResult.success("查询成功", list);
        } catch (Exception e) {
            log.error("按专业 {} 查询学生时发生异常", majorId, e);
            return ResponseResult.failure("按专业查询学生时发生异常");
        }
    }

    @Override
    public ResponseResult<List<StudentInfo>> findByDepartmentId(Long departmentId) {
        log.warn("findByDepartmentId 接口被调用，但尚未实现");
        return ResponseResult.failure(501, "接口待实现");
    }

    @Override
    public ResponseResult<List<StudentInfo>> findByGrade(String grade) {
        try {
            List<StudentInfo> list = this.list(new LambdaQueryWrapper<StudentInfo>().eq(StudentInfo::getGrade, grade));
            return ResponseResult.success("查询成功", list);
        } catch (Exception e) {
            log.error("按年级 {} 查询学生时发生异常", grade, e);
            return ResponseResult.failure("按年级查询学生时发生异常");
        }
    }
}